(ns client.client
  (:gen-class)
  (:import (java.net Socket)
	   (java.io PrintWriter BufferedReader InputStreamReader)))

(def *port* (ref 3009))
(def *host* (ref "localhost"))

(defn where-to
  "Gives the client the port and the host where it will connect"
  [port host]
  (dosync (ref-set *port* port))
  (dosync (ref-set *host* host)))

(defn unserialize
  "Method that interprets a string"
  [data]
  (read-string data))


(defn serialize-client
	"Converts structures into strings"
	[data]
	(binding[*print-dup* true]
  		(print-str data))
)

(defn out-of-date-net 
  "Checks with the server if the current database is up-to-date"
  [database hashRec]
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output (serialize-client [database hashRec]))
		(.println output "out-of-date")
		(.flush output)
		(str (read-string (.readLine input)))
		)))


(defn select-net
  "Ask the server to send the records"
  [database]
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output database)
      (.println output "select")
      (.flush output)
      (read-string (.readLine input))
      )))

(defn create-net
  "Ask the server to send the records"
  [database entry]
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output (serialize-client [database entry]))
      (.println output "create")
      (.flush output)
      )))

(defn update-net
  "Ask the server to create a record"
  [database num entry]
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output (serialize-client [database num entry]))
      (.println output "update")
      (.flush output)))
  )

(defn delete-net
  "Ask the server to send the records"
  [database recno]
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output (serialize-client [database recno]))
      (.println output "delete")
      (.flush output)
      ))
  )


(defn describe-net
  "Ask the server to describe the indicated database"
  [database]
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output database)
      (.println output "describe")
      (.flush output)
      (read-string (.readLine input)))))
     
      
(defn connection-test
  "Tests the connection"
  []
  (let [socket (Socket. @*host* @*port*)]
    (with-open [input (BufferedReader. (InputStreamReader. (.getInputStream socket)))
		output (PrintWriter. (.getOutputStream socket))]
      (.println output "test-db")
      (.println output "test")
      (.flush output)
      (println (.readLine input)))))


;(connection-test)
;(describe-net "db-1x2")
